package com.eastedu.superise.handler.question.handler.answerparentheses;

import com.eastedu.common.enums.ContentPart;
import com.eastedu.common.enums.MediaTypeEnum;
import com.eastedu.common.enums.QuestionTypeEnum;
import com.eastedu.common.model.question.Fragment;
import com.eastedu.common.model.question.QuestionItemContent;
import com.eastedu.common.model.question.QuestionMainContent;
import com.eastedu.superise.handler.question.handler.ContentConverter;
import com.eastedu.superise.handler.question.handler.ContentHandler;
import com.eastedu.superise.handler.question.handler.ContentParser;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Predicate;

/**
 * 单选、多选、不定项、判断题的题干新增结构化的作答括号
 *
 * @author Administrator
 */
@Slf4j
public class ChoiceQuestionAnswerParenthesesContentHandler implements ContentHandler {
    private final Map<ContentPart, ContentParser<ContentSummary>> CONTENT_PARSER_MAP = new ConcurrentHashMap<>(10);
    private final Map<ContentPart, ContentConverter> CONTENT_CONVERTER_MAP = new ConcurrentHashMap<>(10);

    private final AtomicInteger count = new AtomicInteger(0);
    private final AtomicInteger structuredCount = new AtomicInteger(0);
    private final AtomicInteger stemCount = new AtomicInteger(0);


    /**
     * Instantiates a new Choice question answer parentheses content handler.
     *
     * @param contentParser    the content parser
     * @param contentConverter the content converter
     */
    public ChoiceQuestionAnswerParenthesesContentHandler(ContentParser<ContentSummary> contentParser, ContentConverter contentConverter) {
        CONTENT_PARSER_MAP.put(ContentPart.STEM, contentParser);
        CONTENT_CONVERTER_MAP.put(ContentPart.STEM, contentConverter);
    }

    @Override
    public <T extends QuestionMainContent<T>> boolean support(T content, MatchType matchType) {
        // 将试题本身与小题合并处理
        List<T> questions = new ArrayList<>(content.getQuestions());
        questions.add(content);

        boolean support = questions.stream()
                .filter(question -> {
                    // 单选、多选、不定项、判断题
                    QuestionTypeEnum questionType = question.getQuestionType();
                    return questionType == QuestionTypeEnum.SINGLE_CHOICE
                            || questionType == QuestionTypeEnum.MULTIPLE_CHOICE
                            || questionType == QuestionTypeEnum.INDEFINITE_CHOICE
                            || questionType == QuestionTypeEnum.JUDGEMENT;
                })
                .anyMatch(t -> {
                    List<QuestionItemContent> stem = t.getStem();
                    // 是否已结构化(首先要排除已结构化的试题)
                    boolean structured = stem.stream().map(QuestionItemContent::getFragments)
                            .flatMap(Collection::stream)
                            .map(Fragment::getMediaType)
                            .anyMatch(mediaTypeEnum -> mediaTypeEnum == MediaTypeEnum.STRUCTURE);
                    if (structured) {
                        // 计数已结构化的试题
                        structuredCount.incrementAndGet();
                    }
                    ContentSummary summaryStem = CONTENT_PARSER_MAP.get(ContentPart.STEM).parse(content.getQuestionId(), stem);
                    log.debug("==================================");
                    log.debug("题干 => {}", summaryStem.toString());
                    log.debug("==================================");
                    return !structured && matchType.getPredicate().test(summaryStem);
                });
        if (support) {
            // 计数支持的试题总数
            count.incrementAndGet();
        }
        return support;
    }

    @Override
    public <T extends QuestionMainContent<T>> void handle(T content) {
        count.incrementAndGet();
        QuestionTypeEnum questionType = content.getQuestionType();
        if (questionType == QuestionTypeEnum.COMPREHENSIVE) {
            List<T> questions = content.getQuestions();
            for (T question : questions) {
                this.handle(question);
            }
        } else if (questionType == QuestionTypeEnum.SINGLE_CHOICE
                || questionType == QuestionTypeEnum.MULTIPLE_CHOICE
                || questionType == QuestionTypeEnum.INDEFINITE_CHOICE
                || questionType == QuestionTypeEnum.JUDGEMENT) {
            // 是否已结构化(首先要排除已结构化的试题)
            List<QuestionItemContent> stem = content.getStem();
            boolean structured = stem.stream().map(QuestionItemContent::getFragments)
                    .flatMap(Collection::stream)
                    .map(Fragment::getMediaType)
                    .anyMatch(mediaTypeEnum -> mediaTypeEnum == MediaTypeEnum.STRUCTURE);
            if (!structured) {
                // 计数已结构化的试题
                stemCount.incrementAndGet();
                CONTENT_CONVERTER_MAP.get(ContentPart.STEM).convert(stem);
            }
        }
    }

    @Override
    public <T extends QuestionMainContent<T>> void handle(T content, Predicate<T> predicate) {

    }


    /**
     * Print.
     */
    public void print() {
        log.info("处理成功的试题总数: {}，结构化成功的题干数量：{}，过滤已结构化的题干数量：{}", count.get(), stemCount.get(), structuredCount.get());
        CONTENT_PARSER_MAP.get(ContentPart.STEM).print();
    }
}
